package cluster_node.scheduler.job;

import cluster_node.models.GlobalVar;
import cluster_node.models.ReadRequestWrapper;
import cluster_node.scheduler.type_config.TypeDeviceUploadHelper;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import org.eclipse.leshan.core.node.LwM2mNode;
import org.eclipse.leshan.core.node.LwM2mSingleResource;
import org.eclipse.leshan.server.californium.LeshanServer;
import org.eclipse.leshan.server.registration.Registration;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.util.Pool;

import java.util.List;
import java.util.concurrent.CountDownLatch;

public class UploadJob implements Job {

    private final static String UPLOAD_KEY = "AUTO_UP";
    private final static String UPLOAD_ERR = "AUTO_UP_ERR";
    private final static String PREFIX = "#EP#";

    private final static Logger LOG = LoggerFactory.getLogger(UploadJob.class);

    @Override
    @SuppressWarnings("unchecked")
    public void execute(JobExecutionContext jobExecutionContext) {
        LeshanServer server =
                (LeshanServer) jobExecutionContext.getJobDetail().getJobDataMap().get("server");

        TypeDeviceUploadHelper helper =
                (TypeDeviceUploadHelper) jobExecutionContext.getJobDetail().getJobDataMap().get("helper");

        Registration registration =
                (Registration) jobExecutionContext.getJobDetail().getJobDataMap().get("registration");

        Pool<Jedis> jedisPool =
                (Pool<Jedis>) jobExecutionContext.getJobDetail().getJobDataMap().get("jedisPool");

        List<ReadRequestWrapper> requests = helper.getRequests();
        CountDownLatch latch = new CountDownLatch(requests.size());

        // response data
        JsonArray errLog = new JsonArray();
        JsonArray uploads = new JsonArray();

        long begin = System.currentTimeMillis();
        for (ReadRequestWrapper requestWrapper : requests) {
            server.send(registration, requestWrapper.getRequest(), readResponse -> {
                LwM2mNode node = readResponse.getContent();
                JsonObject j = new JsonObject();
                long timestamp = System.currentTimeMillis();

                if (node instanceof LwM2mSingleResource) {
                    j.add("device_id", registration.getEndpoint());
                    j.add("object_id", requestWrapper.getObjectId());
                    j.add("resource_id", requestWrapper.getResourceId());
                    j.add("timestamp", timestamp);
                    j.add("value_type", ((LwM2mSingleResource) node).getType().toString());
                    j.add("value", ((LwM2mSingleResource) node).getValue().toString());

                    uploads.add(j);
                } else {

                    errLog.add("[Multi-Err]: " + readResponse.toString());
                }

                latch.countDown();
            }, e -> {
                errLog.add("[Unknown-Err]: " + e.getMessage());
                latch.countDown();
            });
        }

        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        try (Jedis jedis = jedisPool.getResource()) {
            String fieldName = PREFIX + registration.getEndpoint();
            if (!uploads.isEmpty()) {
                jedis.hset(UPLOAD_KEY, fieldName, uploads.toString());
            }
            if (!errLog.isEmpty()) {
                jedis.sadd(UPLOAD_ERR, errLog.toString());
            }
        }
    }
}
